#include "ServiceHandle.h"
#include <fstream>
#include <QProcess>
#include <iostream>
#include <direct.h>
#include "Command.h"
#include "SystemCtrl.h"

static int64_t g_nCnt =0;
ServiceHandle::ServiceHandle()
    : m_bRunning(false)
{
}


ServiceHandle::~ServiceHandle()
{

}

void ServiceHandle::DoClean()
{
    m_objWork.Stop();
}

void ServiceHandle::InstallService(const std::string& strServiceName/* = ""*/)
{
    auto strPath = Utils::GetRunningPath();
    std::cout << "Exe path: " << strPath << "\n";
    std::string strName = strServiceName.empty()? "CustomService": strServiceName;
    m_strServiceName = strName;
    std::string strCmd = "sc create " + strName + " binpath= " + strPath;
    std::string strResponse = Utils::CommandHelper::ExecCommand(strCmd);
    std::cout << strResponse;

    // set startup with system
    set_auto_start(strName);

    // set failure action(self guard)
    set_failure_config(strName);

    // start service
    StartService(strName);
}

void ServiceHandle::StartService(const std::string& strServiceName)
{
    std::string strCmd = "net start " + strServiceName;
    std::string strResponse = Utils::CommandHelper::ExecCommand(strCmd);
    std::cout << strResponse;
}

void ServiceHandle::StopService(const std::string& strServiceName)
{
    std::string strCmd = "net stop " + strServiceName;
    std::string strResponse = Utils::CommandHelper::ExecCommand(strCmd);
    std::cout << strResponse;
}

void ServiceHandle::UninstallService(const std::string& strServiceName)
{
    StopService(strServiceName);
    std::string strCmd = "sc delete " + strServiceName;
    std::string strResponse = Utils::CommandHelper::ExecCommand(strCmd);
    std::cout << strResponse;
}

void ServiceHandle::start()
{
    g_nCnt = 0;
    m_objWork.Start(std::bind(&ServiceHandle::do_work, &SERVER_CTRL_INST), 2000);
}

void ServiceHandle::pause()
{
    stop();
}

void ServiceHandle::resume()
{
    start();
}

void ServiceHandle::stop()
{
    std::fstream fout("C:\\ProgramData\\CustomServiceState.log", std::ios::out | std::ios::app);
    if(fout.is_open()) {
        fout << "Server stop invok\n";
        fout.close();
    }
    m_objWork.Stop();
}

void ServiceHandle::set_auto_start(const std::string& strServiceName)
{
    std::string strCmd = "sc config " + strServiceName + " start= AUTO";
    std::string strResponse = Utils::CommandHelper::ExecCommand(strCmd);
    std::cout << "\n" << strResponse << "\n";
}

void ServiceHandle::set_failure_config(const std::string& strServiceName)
{
    std::string strCmd = "sc failure " + strServiceName + " reset= 0 actions= restart/500";
    std::string strResponse = Utils::CommandHelper::ExecCommand(strCmd);
    std::cout << "\n" << strResponse << "\n";
}

void ServiceHandle::do_work()
{
    std::fstream fout("C:\\ProgramData\\CustomService.log", std::ios::out | std::ios::app);
    if(fout.is_open()) {
        fout << "Server do work: " << ++g_nCnt << "\n";
        fout.close();
    }
}

bool ServiceHandle::check_server_running(const std::string& strServiceName)
{
    std::string strCmd = "sc query " + strServiceName;
    std::string strResponse = Utils::CommandHelper::ExecCommand(strCmd);
    //std::cout << "\n" << strResponse << "\n";

    if(strResponse.find("RUNNING") != std::string::npos)
        return true;

    return false;
}
